const moment = require('moment');
const { User, Room, UserRoomHistory, UserRoomInRelation } = require("../model")
const _ = require("lodash")
const RecordController = require("./record_controller");
const { Op, where } = require("sequelize");
const bcypt = require("../utils/bcypt")

module.exports = {
  /**
   * 获取学生用户的完整信息
   * @param {Number} userId
   */
  async getStudentInfo(userId) {
    const student = await User.findOne({
      where: { id: userId },
      attributes: { exclude: ["password", "deletedAt"] }
    })
    const room = await student.getRoom()
    const floor = await room?.getFloor()
    const building = await floor?.getBuilding()
    const getupProb = await RecordController.getUserProbability("getup", userId)
    const backProb = await RecordController.getUserProbability("back", userId)
    const cleanProb = await RecordController.getUserProbability("clean", userId)
    const facultyName = await student.getFaculty().then(faculty => faculty?.name)
    const majorName = await student.getMajor().then(major => major?.name)
    const info = Object.assign(student.dataValues, {
      roomNumber: room?.number,
      floorId: floor?.id,
      floorLayer: floor?.layer,
      buildingId: building?.id,
      buildingName: building?.name,
      getupProb,
      backProb,
      cleanProb,
      facultyName,
      majorName
    })
    return info
  },

  /**
   * 获取学生用户们的完整信息
   * @param {Array} users
   */
  async getStudentsInfo(users) {
    const cloneUsers = _.cloneDeep(users)
    for (let user of cloneUsers) {
      delete user.dataValues.password
      delete user.dataValues.deletedAt
      const room = await user.getRoom()
      const floor = await room.getFloor()
      const building = await floor.getBuilding()
      Object.assign(user.dataValues, {
        roomNumber: room.number,
        floorId: floor.id,
        floorLayer: floor.layer,
        buildingId: building.id,
        buildingName: building.name
      })
    }
    return cloneUsers
  },

  async setStudentRoomNull(id) {
    const student = await User.findOne({ where: { id, role: "student" } })
    const result = await student.update({ roomId: null })
    return result
  },
  // 分页获取未分配用户数据
  async getNoFenpeiPageInfo({
    current, step
  }) {
    // 获取数据
    let result = await User.findAndCountAll({
      where: {
        roomId: null,
        role: 'student'
      },
      limit: step,
      offset: step * (current - 1),
      order: [["createdAt", "DESC"]]
    })
    let rows = []
    for (let record of result.rows) {
      record = record.toJSON()
      record.time = moment(new Date(record.createdAt)).format('MM-DD HH:mm')

      const student = await User.findOne({
        where: { id: record.id },
        attributes: { exclude: ["password", "deletedAt"] }
      })

      const facultyName = await student.getFaculty().then(faculty => faculty?.name)
      const majorName = await student.getMajor().then(major => major?.name)

      record.facultyName = facultyName
      record.majorName = majorName

      rows.push(record)
    }
    result.rows = rows;
    return result
  },

  async updateUserInfo(submitInfo) {
    const updateUserId = submitInfo.userId
    const userInfo = await User.findOne({ where: { id: updateUserId } })
    // room是否有值，并且与数据库的不一致则是调整宿舍
    if (submitInfo.roomId && submitInfo.roomId !== userInfo.roomId) {
      // 是否超员？
      const roomInfo = await Room.findOne({ where: { id: submitInfo.roomId } });
      const targetRoomCount = await User.count({ where: { roomId: submitInfo.roomId } });
      if (targetRoomCount >= roomInfo.peopleNum) {
        console.log("targetRoomCount", targetRoomCount)
        console.log("limited", roomInfo.peopleNum)
        throw new Error("更新失败：当前宿舍已满员，请更换其他宿舍")
      }
      // 更新到历史入住
      const histoty = {
        roomId: submitInfo.roomId,
        userId: updateUserId,
        checkTime: new Date()
      }
      UserRoomHistory.createHistory(histoty)
      //更新现在入住关系
      const relation = {
        roomId: submitInfo.roomId,
        userId: updateUserId,
        facultyId: userInfo.facultyId,
        majorId: userInfo.majorId,
        sex: userInfo.sex
      }
      UserRoomInRelation.destroy({ where: { userId: updateUserId } })
      UserRoomInRelation.createRelation(relation)
      // 更新房间的已入住人数
      roomInfo.alreadyNum = targetRoomCount + 1
      if (roomInfo.alreadyNum < roomInfo.peopleNum) {
        roomInfo.status = 1
      } else {
        roomInfo.status = 2
      }
      roomInfo.save(roomInfo);
      if (userInfo.roomId) {
        const oldRoomInfo = await Room.findOne({ where: { id: userInfo.roomId } });
        if (oldRoomInfo != null) {
          // 更新原房间的已入住人数
          oldRoomInfo.alreadyNum = oldRoomInfo.alreadyNum - 1
          if (oldRoomInfo.alreadyNum < oldRoomInfo.peopleNum) {
            oldRoomInfo.status = 1
          } else {
            oldRoomInfo.status = 2
          }
          oldRoomInfo.save(oldRoomInfo);
        }
      }
    }
    for (let itemKey in submitInfo) {
      if (
        Object.hasOwnProperty.call(userInfo.toJSON(), itemKey) &&
        ![undefined, null, ""].includes(submitInfo[itemKey])
      ) {
        userInfo[itemKey] = submitInfo[itemKey]
      }
    }
    if (submitInfo.password) {
      userInfo.password = bcypt.hash(submitInfo.password)
    }
    return userInfo.save()
  },

  // 分页获取已分配用户数据
  async getFenpeiedPageInfo({ current, step, buildingId, floorId, roomId, keyword }) {

    let condition = {
      roomId: { [Op.not]: null },
      role: 'student'
    }
    let roomIds = []
    if (roomId != null && roomId != '') {
      condition.roomId = roomId;
    } else if (floorId != null && floorId != '') {
      const rooList = await Room.findAll({
        where: {
          floorId,
          buildingId
        },
        attributes: ['id']
      });
      rooList.forEach(item => {
        roomIds.push(item.id)
      })
      condition.roomId = { [Op.in]: roomIds }
    } else if (buildingId != null && buildingId != '') {
      const rooList = await Room.findAll({
        where: {
          buildingId
        },
        attributes: ['id']
      });
      rooList.forEach(item => {
        roomIds.push(item.id)
      })
      condition.roomId = { [Op.in]: roomIds }
    }

    if (keyword != null && keyword != '') {
      condition[Op.or] = [
        { name: { [Op.like]: `%${keyword}%` } },
        { account: { [Op.like]: `%${keyword}%` } }]
    }

    console.log("房间的id集合：", roomIds)
    console.log("查询条件", condition)

    // 获取数据
    let result = await User.findAndCountAll({
      where: condition,
      limit: step,
      offset: step * (current - 1),
      order: [["createdAt", "DESC"]]
    })
    let rows = []
    for (let record of result.rows) {
      record = record.toJSON()
      record.time = moment(new Date(record.createdAt)).format('MM-DD')
      record.date = moment(new Date(record.createdAt)).format('YYYY-MM-DD')

      const student = await User.findOne({
        where: { id: record.id },
        attributes: { exclude: ["password", "deletedAt"] }
      })
      const room = await student.getRoom()
      const floor = await room?.getFloor()
      const building = await floor?.getBuilding()
      const facultyName = await student.getFaculty().then(faculty => faculty?.name)
      const majorName = await student.getMajor().then(major => major?.name)

      record.userId = record.id
      record.roomNumber = room?.number
      record.floorId = floor?.id
      record.floorLayer = floor?.layer
      record.buildingId = building?.id
      record.buildingName = building?.name
      record.facultyName = facultyName
      record.majorName = majorName
      rows.push(record)
    }
    result.rows = rows;
    return result
  },

}
